<template>
  <div class="myImg-box" :style="styleObj" v-loading="loading" ref="imgBoxRef"></div>
</template>

<script setup>
import { onMounted, ref, computed } from 'vue'

const props = defineProps({
  width: {
    type: String,
    default: '200px'
  },

  height: {
    type: String,
    default: '200px'
  },

  imgObj: {
    type: Object,
    default: () => {
      return {
        url: 'https://www.walmark.hu/getattachment/0c8599cc-8483-41c3-8abc-274e774ca0b4/koncentralt-keszitmenyek?variant',
        alt: '图片加载失败的是时候显示文字信息'
      }
    }
  }
})

const styleObj = computed(() => {
  return {
    width: props.width,
    height: props.height
  }
})

const imgBoxRef = ref()

const loading = ref(false) // 图片加载loading

const createImg = () => {
  loading.value = true

  const imgObj = new Image()
  imgObj.className = 'img-style'

  imgObj.onload = function () {
    const min = 100
    const max = 300
    const times = Math.floor(Math.random() * (max - min + 1) + min)
    setTimeout(() => {
      imgBoxRef.value.appendChild(imgObj)
      loading.value = false
    }, times)
  }

  imgObj.onerror = function () {
    loading.value = false

    const div = document.createElement('div')
    div.className = 'text-style'
    div.innerHTML = props.imgObj.alt

    imgBoxRef.value.appendChild(div)
  }

  imgObj.src = props.imgObj.url
}

const hasRender = ref(false) // 图片是否渲染
const initFn = () => {
  const intersectionObserver = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        if (!hasRender.value) {
          createImg()
          hasRender.value = true
        }
      }
    })
  })
  intersectionObserver.observe(imgBoxRef.value)
}

onMounted(() => {
  initFn()
})
</script>

<style lang="scss">
.myImg-box {
  border: 1px solid #f2f2f2;
  border-radius: 3px;
  padding: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  .img-style {
    width: 100%;
  }
  .text-style {
    width: 100%;
    height: 100%;
    overflow: auto;
    text-align: justify;
  }
}
</style>
